/**
 * 拖拽插件
 * Created by kongjing on 2016/9/8.
 * v1.3
 */
(function ($) {
    var fromflag = "dragbox-from";
    var toflag = "dragbox-to";
    var moveingpointerclass = "moveingpointer";
    var activeclass = "active";
    var copyactiveclass = "copyactive";
    var dragcallback = "dragcallback";
    var instances = {};
    this._parentbox = undefined;
    var drag = function (target, opts) {
        this.target = target;
        this.data = { sx: 0, sy: 0, state: 0 };
        this.replace = target.data("dragbox") == "replace" || false;
        this.opts = opts;
        var that = this;
        that._cache_top = 0;
        that._cache_left = 0;
        $(window).on("scroll", function () {
            if (!that.data.obj || !that.data) return;
            that.neetfix = true;
            //    var scrolltop = $(this).scrollTop();
            //    var scrollleft= $(this).scrollLeft();
            //    var dtop = scrolltop - that._cache_top || scrolltop;
            //    var dleft = scrollleft - that._cache_left || scrollleft;
            //    var pos = that.data.obj.position();
            //    that.data.obj.css({ "top": dtop + pos.top, "left": dleft + pos.left });
            //    that._cache_top = scrolltop;
            //    that._cache_left = scrollleft;
        })
    }
    drag.prototype = {
        _test: function () {

            if (this.data && this.data.obj) {
                var pos = this.data.obj.position();
                console.log("top:" + pos.top + ",left:" + pos.left);
                console.log("_cache_top:" + this._cache_top + ",_cache_left:" + this._cache_left);
            }
        },
        _fixposition: function (e) {
            if (!this.data || !this.data.obj) return;
            this.neetfix = false;
            var offset = this.data.obj.offset();
            var scrolltop = $(window).scrollTop();
            var scrollleft = $(window).scrollLeft();
            var mouse_x = e.clientX,
                mouse_y = e.clientY,
                obj_x = offset.left,
                obj_y = offset.top,
                obj_width = this.data.obj.width(),
                obj_height = this.data.obj.height();
            var _mouse_x = mouse_x + scrollleft, _mouse_y = mouse_y + scrolltop;
            if (_mouse_x > obj_x && _mouse_y > obj_y && _mouse_x < obj_x + obj_width && _mouse_y < obj_y + obj_height) return;
            var pos = this.data.obj.position();
            var new_obj_left =pos.left + scrollleft-this.startscroll_left;
            var new_obj_top =pos.top +scrolltop-this.startscroll_top;
            console.log("目标原始坐标:("+(pos.left)+","+(pos.top)+")");
            console.log("目标修复后坐标:("+(new_obj_left)+","+(new_obj_top)+")");
            console.log("目标修复坐标偏移量:("+(new_obj_left-pos.left)+","+(new_obj_top-pos.top)+")");
            this.data.obj.css({ "left": new_obj_left, "top": new_obj_top });
            this.startscroll_top = $(window).scrollTop();
            this.startscroll_left = $(window).scrollLeft();
        },
        _dragstart: function (e) {
            e.stopPropagation();
            document.body.onselectstart = document.body.ondrag = function () {
                return false;
            }
            var obj = $(e.target);
            var pos = obj.position();
            obj.css({ "left": pos.left, "top": pos.top });
            if (!$("." + copyactiveclass).is("div")) {
                var copy_div = $("<div/>");
                copy_div.addClass(copyactiveclass).css({ width: obj.width(), height: obj.height() });
            }
            copy_div.insertAfter(obj);
            this.data = { sx: e.clientX, sy: e.clientY, state: 1, obj: obj, copy_div: copy_div };
            this.data.obj.addClass(activeclass);
            this.neetfix = false;
            this.startscroll_top = $(window).scrollTop();
            this.startscroll_left = $(window).scrollLeft();
        },
        _draging: function (e) {
            e.stopPropagation();
            if (!(this.data && this.data.state == 1 && this.data.obj.size() > 0)) return;
            $("body").addClass(moveingpointerclass);
            if (!this.neetfix) {
                var pos = this.data.obj.position();
                var move_pos_x = pos.left + (e.clientX - this.data.sx);
                var move_pos_y = move_pos_y = pos.top + (e.clientY - this.data.sy);
                this.data.sx = e.clientX;
                this.data.sy = e.clientY;
                if (e.clientY > 0 && e.clientX > 0) {
                    this.data.obj.css({ "left": move_pos_x, "top": move_pos_y });
                }
                else if (e.clientY <= 0) {
                    this.data.obj.css({ "left": move_pos_x });
                }
                else {
                    this.data.obj.css({ "top": move_pos_y });
                }
            }
            else {
                this._fixposition(e);
            }
        },
        _dragfinish: function (e) {
            document.body.onselectstart = document.body.ondrag = function () {
                return true;
            }
            if (this.opts.behavior == "replace") {

                if (!this._replace(e)) {
                    this.data.obj.removeClass(activeclass);
                }
            }
            else if (this.opts.behavior = "insert") {
                if (!this._insert(e)) {
                    this.data.obj.removeClass(activeclass);
                }
            }
            else {
                console.log("behavior 不存在" + this.opts.behavior);
            }
            this.data && this.data.copy_div && this.data.copy_div.length > 0 && this.data.copy_div.remove();
            $("body").removeClass(moveingpointerclass);
            this.data = { sx: 0, sy: 0, state: 0 };
        },
        _getregion: function (obj) {
            var pos = obj.offset();
            var width = obj.outerWidth();
            var height = obj.outerHeight();
            var that = this;
            var s_left = $(window).scrollLeft();
            var s_top = $(window).scrollTop();
            return {
                xstart: pos.left - s_left,
                xend: pos.left - s_left + width,
                ystart: pos.top - s_top,
                yend: pos.top - s_top + height
            };
        },
        _checkMouseInRegion: function (mousepoint, region) {
            return mousepoint.x > region.xstart && mousepoint.x < region.xend && mousepoint.y > region.ystart && mousepoint.y < region.yend;
        },
        _getMousePosInContainer: function (e) {
            return { x: e.clientX, y: e.clientY };
        },
        _getbox: function (e) {
            var that = this;
            var retbox;
            if (!this.data || !this.data.obj) return;
            var mpos = that._getMousePosInContainer(e);
            $("[data-" + toflag + "='" + this.data.obj.data(fromflag) + "']").each(function () {
                if (that._checkMouseInRegion(mpos, that._getregion($(this)))) {
                    retbox = $(this)
                    return false;
                }
            });
            return retbox;
        },
        _insert: function (e) {
            var retbox = this._getbox(e);
            if (retbox) {
                this.data.obj.removeClass(activeclass);
                this.data.copy_div.remove();
                if (this.data.obj.parent("[data-" + toflag + "]")[0] != retbox[0]) {
                    var ret = true;
                    this.opts[dragcallback] && (ret = this.opts[dragcallback](this.data.obj, retbox));
                    if (ret != false) {
                        retbox.append(this.data.obj);
                    }
                }
                return true;
            }
            return false
        },
        _replace: function (e) {
            var retbox = this._getbox(e);
            if (retbox) {
                this.data.obj.removeClass(activeclass);
                if (this.data.obj.parent("[data-" + toflag + "]")[0] != retbox[0]) {
                    var ret = true;
                    this.opts[dragcallback] && (ret = this.opts[dragcallback](this.data.obj, retbox));
                    if (ret != false) {
                        this.data.obj.insertAfter(retbox)
                        this.data.obj.insertAfter(retbox);
                        retbox.insertAfter(this.data.copy_div);
                    }
                }
                this.data.copy_div.remove();
                return true;
            }
            return false
        }
    }
    Ez = window["Ez"] || {}
    Ez.dragInit = function (opts) {
        if (typeof (opts) == 'function') {
            var fn = opts;
            opts = {};
            opts[dragcallback] = fn;
        }
        var cfg = $.extend(opts, {
            behavior: "insert",
            dragScopeSelector: ".dragbox-area"
        })
        var currentidentity;

        $(document).on("mousedown mousemove mouseup", function (e) {
            if (e.type == "mousedown") {
                if ($(e.target).hasClass("nodrag")) return;
                var obj = e.target = $(e.target).closest("[data-" + fromflag + "]");
                currentidentity = obj.data(fromflag);
                if (currentidentity === undefined) return;
                $(this).on("preventDefault", function () {
                    if (e && e.preventDefault) e.preventDefault();
                    else window.event.returnValue = false;
                }).trigger("preventDefault");
                if (!instances[currentidentity]) {
                    var rel_pos = obj.closest(cfg.dragScopeSelector).position();
                    instances[currentidentity] = new drag(obj, $.extend(cfg, { top: rel_pos.top, left: rel_pos.left }));
                }
                instances[currentidentity]._dragstart(e);
            }
            else if (e.type == "mousemove") {
                if (!instances[currentidentity]) return;

                instances[currentidentity]._draging(e);
            }
            else if (e.type == "mouseup") {
                if (!instances[currentidentity]) return;
                instances[currentidentity]._dragfinish(e);

                $(this).off("preventDefault");
            }
        })
    }
})(jQuery)